#include "LogicSystem.h"
#include <json/json.h>
#include <json/value.h>
#include <json/reader.h>
void LogicSystem::HelloCallBack(std::shared_ptr<LogicNode> logic_node)
{
	auto session = logic_node->_session;
	auto recv_node = logic_node->_recv_node;
	Json::Reader reader;
	Json::Value root;
	reader.parse(recv_node->_data, root);
	std::cout << "recevie msg is " << root << std::endl;
	Json::Value send;
	send["data"] = "server has received " + root["data"].asString();
	send["id"] = root["id"].asInt();
	std::string send_json = send.toStyledString();
	session->Send(send["id"].asInt(),send_json.c_str(),send_json.size());
}

LogicSystem::LogicSystem() :_b_stop(false), _work_thread([this](){
	DealMsg();
	}) {
	RegisteredCallBack();
}
void LogicSystem::RegisteredCallBack() {
	_callback_functions[MSG_HELLO_WORD] = std::bind(&LogicSystem::HelloCallBack, this, std::placeholders::_1);
}

LogicSystem& LogicSystem::GetInstance()
{
	static LogicSystem logicsystem;
	return logicsystem;
}

LogicSystem::~LogicSystem()
{
	_b_stop = true;
	_consume.notify_one();
	_work_thread.join();
}

void LogicSystem::PostToLogic(std::shared_ptr<Session> session, std::shared_ptr<RecvNode> recv_node)
{
	std::unique_lock<std::mutex> lock(_mutex);
	_logic_queue.emplace(std::make_shared<LogicNode>(session, recv_node));
	if (_logic_queue.size() == 1) {
		_consume.notify_one();
	}
}

void LogicSystem::DealMsg()
{
	while (true) {
		std::unique_lock<std::mutex> lock(_mutex);
		while (_logic_queue.empty() && !_b_stop) {
			_consume.wait(lock);
		}
		if (_b_stop) {
			while (!_logic_queue.empty()) {
				auto front = _logic_queue.front();
				auto function_iter = _callback_functions.find(front->_recv_node->_msg_id);
				if (function_iter == _callback_functions.end()) {
					_logic_queue.pop();
					continue;
				}
				function_iter->second(front);
				_logic_queue.pop();
			}
			break;
		}
		auto front = _logic_queue.front();
		auto function_iter = _callback_functions.find(front->_recv_node->_msg_id);
		if (function_iter == _callback_functions.end()) {
			_logic_queue.pop();
			continue;
		}
		function_iter->second(front);
		_logic_queue.pop();

	}
}
